import math

def main():
    import sys
    input = sys.stdin.read  # 使用更快的输入方式
    data = input().split()  # 读取所有输入数据
    idx = 0  # 当前处理的数据索引

    # 读取数组长度和操作次数
    n, m = int(data[idx]), int(data[idx + 1])
    idx += 2

    # 读取初始数组
    a = list(map(int, data[idx: idx + n]))
    idx += n

    # 计算块大小和块数量
    block_size = int(math.sqrt(n)) + 1  # 块大小为√n，向上取整
    num_blocks=n//block_size+1  # 计算需要的块数量

    # 初始化块信息
    sum_block = [0] * num_blocks  # 每个块的和
    lazy = [0] * num_blocks       # 每个块的延迟标记（表示该块整体需要加的值）

    # 初始化每个块的和
    for i in range(n):
        block_idx = i // block_size  # 计算当前元素所属的块索引
        sum_block[block_idx] += a[i]  # 累加到对应块的和中

    # 处理每个操作
    for _ in range(m):
        # 根据操作类型读取参数
        if data[idx] == '1':  # 区间修改操作
            op, l, r, k = data[idx], int(data[idx + 1]) - 1, int(data[idx + 2]) - 1, int(data[idx + 3])
            idx += 4
        else:  # 区间查询操作
            op, l, r = data[idx], int(data[idx + 1]) - 1, int(data[idx + 2]) - 1
            idx += 3

        # 计算左右端点所在的块
        left_block = l // block_size
        right_block = r // block_size

        if op == '1':  # 区间修改操作
            if left_block == right_block:  # 操作区间在同一个块内
                for i in range(l, r + 1):  # 直接逐个元素修改
                    a[i] += k
                    sum_block[left_block] += k
            else:  # 操作区间跨越多个块
                # 处理左部分块（不完整的块）
                for i in range(l, (left_block + 1) * block_size):
                    a[i] += k
                    sum_block[left_block] += k
                # 处理右部分块（不完整的块）
                for i in range(right_block * block_size, r + 1):
                    a[i] += k
                    sum_block[right_block] += k
                # 处理中间的完整块
                for block in range(left_block + 1, right_block):
                    lazy[block] += k  # 更新延迟标记
                    sum_block[block] += k * block_size  # 更新块的和（每个元素加k）
        else:  # 区间查询操作
            total = 0  # 存储查询结果
            if left_block == right_block:  # 查询区间在同一个块内
                for i in range(l, r + 1):
                    total += a[i] + lazy[left_block]  # 元素值加上延迟标记
            else:  # 查询区间跨越多个块
                # 处理左部分块
                for i in range(l, (left_block + 1) * block_size):
                    total += a[i] + lazy[left_block]
                # 处理右部分块
                for i in range(right_block * block_size, r + 1):
                    total += a[i] + lazy[right_block]
                # 处理中间的完整块
                for block in range(left_block + 1, right_block):
                    total += sum_block[block]  # 直接加上整个块的和（已经包含延迟标记的影响）
            print(total)  # 输出查询结果

if __name__ == "__main__":
    main()